﻿using System.Collections.Generic;
using Game;

namespace Mekiasm
{
    /// <summary>
    /// 用于展示合成普，不能进行其它任何操作
    /// </summary>
    public class ComponentCraftDemoMachine : ComponentEnergyMachine
    {
        private int[] m_CraftSlotIndies;

        private int[] m_FuelCraftSlotIndies;

        private int[] m_RemainSlotIndies;

        private int[] m_ResultSlotIndies;

        class Item
        {
            public Slot slot;
            public List<int> list;
            public byte position;
            public bool fuel;
        }

        public void SetData(MekRecipe mekRecipe, int SlotsCount, int[] CraftSlotIndies, int[] FuelCraftSlotIndies, int[] RemainSlotIndies, int[] ResultSlotIndies)
        {
            this.SlotsCount = SlotsCount;
            Slots.Clear();
            for (int i = 0; i < SlotsCount; i++) { Slots.Add(new Slot()); }
            m_CraftSlotIndies = CraftSlotIndies;
            m_FuelCraftSlotIndies = FuelCraftSlotIndies;
            m_RemainSlotIndies = RemainSlotIndies;
            m_ResultSlotIndies = ResultSlotIndies;
            for (int i = 0; i < m_CraftSlotIndies.Length; i++)
            {
                if (i < mekRecipe.ingredians.Length)
                {
                    var slotIndex = m_CraftSlotIndies[i];
                    var slot = Slots[slotIndex];
                    if (!string.IsNullOrEmpty(mekRecipe.ingredians[i]))
                    {
                        slot.Count = 1;
                        RegisterList(slot, FindBlocksByCraftingId(mekRecipe.ingredians[i]), false);
                    }
                }
            }
            for (int i = 0; i < m_FuelCraftSlotIndies.Length; i++)
            {
                if (i < mekRecipe.fuelIngredians.Length)
                {
                    var slotIndex = m_FuelCraftSlotIndies[i];
                    var slot = Slots[slotIndex];
                    if (!string.IsNullOrEmpty(mekRecipe.fuelIngredians[i]))
                    {
                        slot.FuelType = mekRecipe.fuelIngredianTypes[i];
                        slot.FuelAmount = mekRecipe.fuelIngrediansAmount[i];
                        slot.FuelCapacity = mekRecipe.fuelIngrediansAmount[i];
                        RegisterList(slot, FindBlocksByCraftingId(mekRecipe.fuelIngredians[i]), true);
                    }
                }
            }
            for (int i = 0; i < m_RemainSlotIndies.Length; i++)
            {
                if (i < mekRecipe.Remains.Length)
                {
                    var slotIndex = m_RemainSlotIndies[i];
                    var slot = Slots[slotIndex];
                    if (mekRecipe.RemainCounts[i] > 0)
                    {
                        slot.Count = mekRecipe.RemainCounts[i];
                        slot.Value = mekRecipe.Remains[i];
                    }
                }
            }
            for (int i = 0; i < m_ResultSlotIndies.Length; i++)
            {
                if (i < mekRecipe.Results.Length)
                {
                    var slotIndex = m_ResultSlotIndies[i];
                    var slot = Slots[slotIndex];
                    if (mekRecipe.ResultCounts[i] > 0)
                    {
                        slot.Count = mekRecipe.ResultCounts[i];
                        slot.Value = mekRecipe.Results[i];
                    }
                }
            }
            for (int i = 0; i < m_ResultSlotIndies.Length; i++)
            {
                if (i < mekRecipe.FuelResults.Length)
                {
                    var slotIndex = m_ResultSlotIndies[i];
                    var slot = Slots[slotIndex];
                    if (mekRecipe.FuelAmountResults[i] > 0)
                    {
                        slot.FuelAmount = mekRecipe.FuelAmountResults[i];
                        slot.FuelValue = mekRecipe.FuelResults[i];
                        slot.FuelType = mekRecipe.FuelResultTypes[i];
                    }
                }
            }
        }

        List<Item> Items = new List<Item>();

        public void RegisterList(Slot slot, List<int> list,bool fuel)
        {
            var item = new Item() { slot = slot, list = list, position = 0, fuel = fuel };
            Items.Add(item);
            if (item.fuel)
            {
                item.slot.FuelValue = item.list[item.position];
            }
            else
            {
                item.slot.Value = item.list[item.position];
            }
        }

        public void Update()
        {
            CraftProgress += Engine.Time.FrameDuration * 0.2f;
            if (CraftProgress > 1f) CraftProgress = 0;

            if (Engine.Time.PeriodicEvent(2.0, 1.5))
            {
                for (int i = 0; i < Items.Count; i++)
                {
                    var item = Items[i];
                    ++item.position;
                    if (item.position == item.list.Count) item.position = 0;
                    if (item.fuel)
                    {
                        item.slot.FuelValue = item.list[item.position];
                    }
                    else
                    {
                        item.slot.Value = item.list[item.position];
                    }
                }
            }
        }

        public List<int> FindBlocksByCraftingId(string craftingId)
        {
            List<int> vs = new List<int>();
            if (craftingId.Contains(":"))
            {
                CraftingRecipesManager.DecodeIngredient(craftingId, out var cid, out var data);
                var list = BlocksManager.FindBlocksByCraftingId(cid);
                foreach (var b in list) vs.Add(Terrain.MakeBlockValue(b.BlockIndex, 0, data.HasValue ? data.Value : 0));
            }
            else
            {
                foreach (var b in BlocksManager.Blocks)
                {
                    if (b.CraftingId == craftingId) vs.Add(b.BlockIndex);
                    else
                    {
                        foreach (var v in b.GetCreativeValues())
                        {
                            if (b.GetCraftingId(v) == craftingId) vs.Add(v);
                        }
                    }
                }
            }
            if (vs.Count == 0) throw new System.Exception("没有找到对应配方:" + craftingId);
            return vs;
        }

        public override int GetSlotCapacity(int slotIndex, int value)
        {
            return 0;
        }
        public override void ProcessSlotItems(int slotIndex, int value, int count, int processCount, out int processedValue, out int processedCount)
        {
            processedValue = 0;
            processedCount = 0;
        }
        public override int RemoveSlotItems(int slotIndex, int count)
        {
            return 0;
        }
        public override void AddSlotItems(int slotIndex, int value, int count)
        {
        }
    }
}
